package day09;

/**
 * 匿名内部类
 * @author wangbiao
 *
 */
public class AnonymityInnerClass {
	public static void main(String[] args) {
		new OuterClass().method();
		new OuterClass().function();
		//匿名内部类经常使用到得情形
		//注意：需要传递过去的这样的父类或者接口里面需要实现的方法不要超过3个
		new OuterClass().function(
				new AbstractClass() {
					@Override
					public void show() {
						System.out.println("匿名内部类调用");
					}
				}
		);
		
	}
}
class OuterClass {
	private int x = 3;
	
	//局部内部类
	public void method() {
		//y是局部变量，内部类要调用局部变量必须是被final修饰
		final int y = 5;
		//局部内部类不能被修饰成员的修饰符修饰：比较private、static等
		class InnerClass extends AbstractClass {
			//还持有外部类的引用OuterClass.this
			private int z = 5; // 因为z是InnerClass的成员变量，因此InnerClass可以直接调用
			@Override
			public void show() {
				System.out.println("OuterClass.this.x== " +OuterClass.this.x);
				System.out.println("x== " +x);
				System.out.println("y== " +y);
				System.out.println("z== " +z);
			}
			
		}
		new InnerClass().show();
	}
	
	//匿名内部类
	public void function() {
		//必须是final的
		final int y = 5;
		//匿名内部类，子类对象并直接调用其方法。
		//匿名内部类的前提：内部类必须是继承一个类或者实现一个接口。
		new AbstractClass() {
			//同理可以调用成员变量
			private int z = 3;
			@Override
			public void show() {
				System.out.println("y== "+y);
				System.out.println("z== "+z);
			}
		}.show();
	}
	
	//代码中可能经常会用到的情况
	//重载，并且需要使用匿名内部类
	public void function(AbstractClass abClass) {
		abClass.show();
	}
}
abstract class AbstractClass {
	
	public abstract void show();
}